﻿/**************************************************
 * Quantum Quest Game Project                     *
 *                                                *
 * Version:                                       *
 * Design 1.0                                     *
 *                                                *
 * Authors:                                       *
 * Michael Fowler                                 *
 * Michael Timmins                                *
 * Octavian Geagla                                *
 * Eric Cooper                                    *
 *                                                *
 * License:                                       *
 * Unknown                                        *
 *                                                *
 * ************************************************/

/**************************************************
 * QQVector2.cs                                   *
 *                                                *
 * Created:                                       *
 * 6/15/09, Octavian Geagla                       *
 *                                                *
 * Updated:                                       *
 * 6/16/09                                        *
 *                                                *
 * Description:                                   *
 * 2D Vector Implementation, to be used in        *
 * conjunction with a Math/Physics Engine.        *
 *                                                *
 * ************************************************/


using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace QuantumQuest
{
    public class QQVector2
    {
        double _x;
        double _y;

        double _magnitude;
        double _thetaRad;
        double _thetaDeg;
        

        public QQVector2(double x, double y)
        {
            /*if ((x == 0) & (y == 0))
            {
                throw new Exception("Vector2: Cannot have size zero.");
            }*/
            
            _x = x;
            _y = y;
            _magnitude = Math.Sqrt(_x * _x + _y * _y);
            _thetaRad = CalcThetaRad(_x, _y);
            _thetaDeg = _thetaRad * ((180.0) / (Math.PI));

        }
        public QQVector2()
        {
            _x = 0;
            _y = 0;
            _magnitude = 0;
            _thetaDeg = 0;
            _thetaRad = 0;
        }
        public double X
        {
            get
            {
                return _x;
            }
            set
            {
                _x = value;
                UpdateVector();
            }
        }
        public double Y
        {
            get
            {
                return _y;
            }
            set
            {
                _y = value;
                UpdateVector();
            }
        }

        public double ThetaRad
        {
            get
            {
                return _thetaRad;
            }
            set
            {
                _x = _magnitude * Math.Cos(value);
                _y = _magnitude * Math.Sin(value);
                UpdateVector();
            }
            
        }
        public double ThetaDeg
        {
            get
            {
                return _thetaDeg;
            }
            set
            {
                _x = _magnitude * Math.Cos(value);
                _y = _magnitude * Math.Sin(value);
                UpdateVector();
            }
        }
        public double Magnitude
        {
            get
            {
                return _magnitude;
            }
            set
            {
                _x = value * Math.Cos(_thetaRad);
                _y = value * Math.Sin(_thetaRad);
                UpdateVector();
            }
        }
        public void Normalize()
        {
            _x /= _magnitude;
            _y /= _magnitude;
            UpdateVector();
        }
       
        public static QQVector2 operator -(QQVector2 v1, QQVector2 v2)
        {
            QQVector2 temp = new QQVector2(0, 0);
            temp.X = v1.X - v2.X;
            temp.Y = v1.Y - v2.Y;
            
            return temp;
        }
        public static QQVector2 operator +(QQVector2 v1, QQVector2 v2)
        {
            QQVector2 temp = new QQVector2(0, 0);
            temp.X = v1.X + v2.X;
            temp.Y = v1.Y + v2.Y;
            
            return temp;
        }
        public static QQVector2 operator *(QQVector2 v1,double a)
        {
            QQVector2 temp = v1;
            temp._x *= a;
            temp._y *= a;
            return temp;
        }
        public static QQVector2 operator *(double a, QQVector2 v1)
        {
            QQVector2 temp = v1;
            temp._x *= a;
            temp._y *= a;
            return temp;
        }
        public override bool Equals(object obj)
        {
            if (obj is QQVector2)
            {
                QQVector2 v1 = (QQVector2)(obj);
                return this.Equals(v1);
            }
            else
            {
                return false;
            }            
        }
        public bool Equals(QQVector2 v1)
        {
            return QQVector2.Equals(this,v1);
        }
        public static bool Equals(QQVector2 v1, QQVector2 v2)
        {
            return ((v1.X == v2.X) && (v1.Y == v2.Y));
        }
        public static bool operator ==(QQVector2 v1, QQVector2 v2)
        {
            return QQVector2.Equals(v1, v2);
        }
        public static bool operator !=(QQVector2 v1, QQVector2 v2)
        {
            return !QQVector2.Equals(v1, v2);
        }
        public override int GetHashCode()
        {
            int x = (int)_x;
            int y = (int)_y;

            int a = (int)((_x - x) * 10000);
            int b = (int)((_y - y) * 10000);
            return x ^ y ^ a ^ b;
        }


        public void UpdateVector()
        {
            _magnitude = Math.Sqrt(_x * _x + _y * _y);
            _thetaRad = CalcThetaRad(_x, _y);
            _thetaDeg = _thetaRad * ((180.0) / (Math.PI));
        }
        private double CalcThetaRad(double x, double y)
        {
            double absTheta;

            absTheta = Math.Atan(Math.Abs(y) / Math.Abs(x));

            //quadrant 1
            if ((x > 0) && (y > 0))
            {
                return (absTheta);
            }
            //quadrant 2
            else if ((x < 0) && (y > 0))
            {
                return  (Math.PI - absTheta);
            }
            //quadrant 3
            else if ((x < 0) && (y < 0))
            {
                return (Math.PI + absTheta);
            }
            //quadrant 4
            else if ((x > 0) && (y < 0))
            {
                return ((2.0) * Math.PI - absTheta);
            }
            //cover axes
            else if (x == 0)
            {
                if (y > 0)
                {
                    return  ((Math.PI) / (2.0));
                }
                else if (y < 0)
                {
                    return ((Math.PI) / (2.0 / 3.0));
                }
            }
            else if (y == 0)
            {
                if (x > 0)
                {
                    return (0.0);
                }
                else if (x < 0)
                {
                    return (Math.PI);
                }
            }
            return 0;

        }
       
    }
}
